package com.hubing.cloud.app.web.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.hubing.cloud.app.web.constant.EsConstant;
import com.hubing.cloud.app.web.es.ElasticSearchRestManager;
import com.hubing.cloud.app.web.mapper.DocBrowseMapper;
import com.hubing.cloud.app.web.mapper.DocMapper;
import com.hubing.cloud.app.web.mapper.MenuMapper;
import com.hubing.cloud.app.web.model.GlobalException;
import com.hubing.cloud.app.web.model.dto.DocDto;
import com.hubing.cloud.app.web.model.entity.Doc;
import com.hubing.cloud.app.web.model.entity.DocBrowse;
import com.hubing.cloud.app.web.model.entity.Menu;
import com.hubing.cloud.app.web.service.DocService;
import com.hubing.cloud.app.web.util.DateUtil;
import com.hubing.cloud.app.web.util.Html2TxtUtil;
import com.hubing.cloud.app.web.util.IdUtil;
import com.hubing.cloud.app.web.util.Md2HtmlUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
* @author 81517
* @description 针对表【doc】的数据库操作Service实现
* @createDate 2023-01-31 01:42:54
*/
@Service
public class DocServiceImpl implements DocService {

    @Autowired
    private DocMapper docMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private DocBrowseMapper docBrowseMapper;

    /**
     * 查询 - 文章
     *
     * @param menuId
     * @return
     */
    @Override
    public JSONObject showDoc(String menuId) {
        Example example = new Example(Doc.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("menuId",menuId);
        Doc doc = docMapper.selectOneByExample(example);
        if (null == doc || 0 == doc.getDocStatus()) {
            throw new GlobalException("文章不存在或已删除！");
        }

        Example example2 = new Example(Doc.class);
        Example.Criteria criteria2 = example2.createCriteria();
        criteria2.andEqualTo("docId",doc.getDocId());
        DocBrowse docBrowse = docBrowseMapper.selectOneByExample(example2);

        JSONObject jo = new JSONObject();
        jo.put("docTitle",doc.getDocTitle());
        jo.put("docContent",doc.getDocConent());
        jo.put("updateTime", DateUtil.format(doc.getUpdated()));
        jo.put("viewCount",docBrowse.getCount());

        Map<String, Object> docMap = ElasticSearchRestManager.findById(EsConstant.DOC_INDEX, doc.getDocId());
        jo.put("docHtmlContent",docMap.get("docHtmlContent"));
        jo.put("docTextContent",docMap.get("docTextContent"));
        return jo;
    }

    /**
     * 保存 - 文章
     *
     * @param dto
     * @return
     */
    @Transactional
    @Override
    public Boolean saveDoc(DocDto dto) {
        Date now = new Date();
        String docTitle = dto.getDocTitle();
        String docMdConent = dto.getDocConent();
        String docHtmlContent = Md2HtmlUtil.convert(docMdConent);
        String docTextContent = Html2TxtUtil.convert(docHtmlContent);
        // 添加
        if (StringUtils.isEmpty(dto.getDocId())) {
            // 菜单
            Example example = new Example(Menu.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("menuId",dto.getParentId());
            Menu parent = menuMapper.selectOneByExample(example);
            Integer maxSort = menuMapper.queryMaxSort(parent.getMenuId());

            Menu menu = new Menu();
            BeanUtils.copyProperties(dto,menu);
            menu.setMenuId(IdUtil.getIncreaseIdByCurrentTimeMillis());
            menu.setMenuSort(++maxSort);
            menu.setMenuType(2);
            menu.setCreated(now);
            menu.setUpdated(now);
            menu.setVersion(1L);
            menu.setMenuStatus(1);
            menu.setRootMenuId(null==parent.getParentId() ? parent.getMenuId() : parent.getRootMenuId());
            menu.setMenuDefault(0);
            menu.setMenuName(docTitle);
            String docId = IdUtil.getIncreaseIdByCurrentTimeMillis();
            menu.setDocId(docId);
            menuMapper.insert(menu);

            // 文章
            Doc doc = new Doc();
            doc.setDocId(docId);
            doc.setDocTitle(docTitle);
            doc.setDocConent(dto.getDocConent());
            doc.setMenuId(menu.getMenuId());
            doc.setRootMenuId(menu.getRootMenuId());
            doc.setCreated(now);
            doc.setUpdated(now);
            doc.setVersion(1L);
            doc.setDocStatus(1);
            docMapper.insert(doc);

            Map map = new HashMap();
            map.put("docId",doc.getDocId());
            map.put("docTitle",doc.getDocTitle());
            map.put("docContent", docMdConent);
            map.put("docHtmlContent",docHtmlContent);
            map.put("docTextContent",docTextContent);
            map.put("menuId",doc.getMenuId());
            map.put("rootMenuId",doc.getRootMenuId());
            map.put("docStatus",doc.getDocStatus());
            ElasticSearchRestManager.insert(EsConstant.DOC_INDEX, doc.getDocId(), map);
            //

            // 浏览记录
            DocBrowse docBrowse = new DocBrowse();
            docBrowse.setDocBrowseId(IdUtil.getIncreaseIdByCurrentTimeMillis());
            docBrowse.setDocId(doc.getDocId());
            docBrowse.setCount(0L);
            docBrowse.setCreated(now);
            docBrowse.setVersion(1L);
            docBrowseMapper.insert(docBrowse);
        } else {
            // 更新文章
            Example example = new Example(Doc.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("docId",dto.getDocId());
            Doc doc = docMapper.selectOneByExample(example);
            doc.setDocConent(dto.getDocConent());
            doc.setUpdated(now);
            doc.setVersion(doc.getVersion()+1);
            docMapper.updateByPrimaryKeySelective(doc);

            Map map = new HashMap();
            map.put("docId",doc.getDocId());
            map.put("docTitle",doc.getDocTitle());
            map.put("docContent", docMdConent);
            map.put("docHtmlContent",docHtmlContent);
            map.put("docTextContent",docTextContent);
            map.put("menuId",doc.getMenuId());
            map.put("rootMenuId",doc.getRootMenuId());
            map.put("docStatus",doc.getDocStatus());
            ElasticSearchRestManager.updateByBulk(EsConstant.DOC_INDEX, doc.getDocId(), map);
        }
        return true;
    }

    /**
     * 删除 - 文章
     *
     * @param docId
     * @return
     */
    @Override
    public Boolean deleteDoc(String docId) {
        // 删除文章
        Example example = new Example(Doc.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("docId",docId);
        criteria.andEqualTo("docStatus",1);
        Doc doc = docMapper.selectOneByExample(example);
        if (null == doc || 0 == doc.getDocStatus()) {
            throw new GlobalException("文章不存在或已删除！");
        }
        doc.setDocStatus(0);
        docMapper.updateByPrimaryKeySelective(doc);

        Map map = new HashMap();
        map.put("docStatus",0);
        ElasticSearchRestManager.updateByBulk(EsConstant.DOC_INDEX, doc.getDocId(), map);

        // 删除菜单
        Menu menu = new Menu();
        menu.setMenuId(doc.getMenuId());
        menu.setMenuStatus(0);
        menuMapper.updateByPrimaryKeySelective(menu);

        // 删除浏览记录
        Example example3 = new Example(Menu.class);
        Example.Criteria criteria3 = example3.createCriteria();
        criteria3.andEqualTo("docId",docId);
        docBrowseMapper.deleteByExample(example3);
        return true;
    }
}
